﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using Fuse8.ContentManagementFramework.BizFacade.Services.Contents;
using Fuse8.ContentManagementFramework.BizFacade.Services.Contents.Queryable;
using Fuse8.ContentManagementFramework.Domain;
using Fuse8.DomainFramework.BusinessService;
using Fuse8.DomainFramework.Common;

namespace Fuse8.ContentManagementFramework.Web.MvcPowered.Components
{
    public static class CmsSnippetComponentHtmlHelperExtension
    {
        /// <summary>
        /// Creates <see cref="CmsSnippetComponent"/> object for rendering specified snippet
        /// </summary>
        /// <param name="htmlHelper">Current HtmlHelper</param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static CmsSnippetComponent CmsSnippet(this HtmlHelper htmlHelper, string contentType = null)
        {
            return new CmsSnippetComponent(htmlHelper, contentType);
        }
    }
    
    public class CmsSnippetComponent : CmsMvcBaseComponent<CmsSnippetComponent, string>
    {
        public int ContentId { get; private set; }
        public string Title { get; private set; }
        public string ContentType { get; private set; }
        public IDictionary<string, string> Fields { get; private set; }
        
        public CmsSnippetComponent(HtmlHelper htmlHelper, string contentType) : base(htmlHelper)
        {
            Fields = new ConcurrentDictionary<string, string>();
            if(!string.IsNullOrEmpty(contentType))
            {
                ContentType = contentType;
            }
            else
            {
                ContentType = "Snippet";
            }
            InlineTemplate = p => p;
        }

        

        public CmsSnippetComponent WithContentId(int value)
        {
            ContentId = value;
            return this;
        }

        public CmsSnippetComponent WithTitle(string value)
        {
            Title = value;
            return this;
        }

        public CmsSnippetComponent WithField(string name, string value)
        {
            Fields[name] = value;
            return this;
        }

        protected override string Value
        {
            get
            {
                var type = new BusinessServiceFacade<CmsContentType, int>().FindOne(p => p.ContentTypeName == ContentType);
                string result = "";
                if (type != null)
                {
                    Expression<Func<GenericCmsEntity, bool>> expression = null;
                    if (Fields.Count > 0)
                    {
                        foreach(var f in Fields)
                        {
                            string n = f.Key;
                            string v = f.Value;
                            if (expression != null)
                            {
                                expression = expression.And(p => p.PropertyEquals(n, v));

                            }
                            else
                            {
                                expression = p => p.PropertyEquals(n, v);
                            }
                        }                        
                    }
                    else if (!string.IsNullOrEmpty(Title))
                    {
                        expression = p => p.PropertyEquals("ContentTitle", Title);
                    }
                    else
                    {
                        expression = p => p.PropertyEquals("PublicContentId", ContentId);
                    }

                    if (expression != null)
                    {
                        var item = GenericContentService.GetAll(type.Id).Where(expression).Take(1).ToList().FirstOrDefault();
                        if (item != null)
                        {
                            result = item["ContentBody"].ToString();
                        }
                    }
                }
                return result;
            }
            set
            {
                base.Value = value;
            }
        }
    }
}